package com.yudaob2b.elong.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.metrics.Metric;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

/**
 * 异步监控线程池
 *
 * @author Kidd.Tan
 * @email 298023780@qq.com
 * @date 7/21/18 11:49 AM
 */
@Component
public class AsyncThreadPoolMetricsService {

    public final Logger LOG = LoggerFactory.getLogger(this.getClass());

    private Map<String, ThreadPoolTaskExecutor> targetAsyncThreadPool;

    private static final String pattern = "async.task.%s.%s";

    @Autowired
    private ThreadPoolTaskExecutor dataInvLocalTaskExecutor;

    @Autowired
    private ThreadPoolTaskExecutor dataInvDbTaskExecutor;

    @Resource(name = "incrTaskExecutor")
    private ThreadPoolTaskExecutor incrTaskExecutor;

    @Resource(name = "dataRateLocalTaskExecutor")
    private ThreadPoolTaskExecutor dataRateLocalTaskExecutor;

    @Resource(name = "dataRateDbTaskExecutor")
    private ThreadPoolTaskExecutor dataRateDbTaskExecutor;

    @Autowired
    ApplicationContext context;

    public Collection<Metric<?>> metrics() {
        try {
            if (targetAsyncThreadPool == null || targetAsyncThreadPool.size() == 0) {
                targetAsyncThreadPool = context.getBeansOfType(ThreadPoolTaskExecutor.class);
            }
            Collection<Metric<?>> result = new ArrayList<>();
            /*for (Map.Entry<String, ThreadPoolTaskExecutor> entry: targetAsyncThreadPool.entrySet()) {
                ThreadPoolTaskExecutor executor =  entry.getValue();
                result.add(new Metric<Number>(String.format(pattern, entry.getKey(), "aciveCount"), executor.getActiveCount()));
                result.add(new Metric<Number>(String.format(pattern, entry.getKey(), "currentPoolSize"), executor.getPoolSize()));
                result.add(new Metric<Number>(String.format(pattern, entry.getKey(), "maxPoolSize"), executor.getMaxPoolSize()));
                result.add(new Metric<Number>(String.format(pattern, entry.getKey(), "currentSizeInQueue"), executor.getThreadPoolExecutor().getQueue().size()));
            }*/
            result.add(new Metric<Number>(String.format(pattern, "dataInvLocalTaskExecutor", "aciveCount"), dataInvLocalTaskExecutor.getActiveCount()));
            result.add(new Metric<Number>(String.format(pattern, "dataInvLocalTaskExecutor", "currentPoolSize"), dataInvLocalTaskExecutor.getPoolSize()));
            result.add(new Metric<Number>(String.format(pattern, "dataInvLocalTaskExecutor", "maxPoolSize"), dataInvLocalTaskExecutor.getMaxPoolSize()));
            result.add(new Metric<Number>(String.format(pattern, "dataInvLocalTaskExecutor", "currentSizeInQueue"), dataInvLocalTaskExecutor.getThreadPoolExecutor().getQueue().size()));

            result.add(new Metric<Number>(String.format(pattern, "dataInvDbTaskExecutor", "aciveCount"), dataInvDbTaskExecutor.getActiveCount()));
            result.add(new Metric<Number>(String.format(pattern, "dataInvDbTaskExecutor", "currentPoolSize"), dataInvDbTaskExecutor.getPoolSize()));
            result.add(new Metric<Number>(String.format(pattern, "dataInvDbTaskExecutor", "maxPoolSize"), dataInvDbTaskExecutor.getMaxPoolSize()));
            result.add(new Metric<Number>(String.format(pattern, "dataInvDbTaskExecutor", "currentSizeInQueue"), dataInvDbTaskExecutor.getThreadPoolExecutor().getQueue().size()));

            result.add(new Metric<Number>(String.format(pattern, "incrTaskExecutor", "aciveCount"), incrTaskExecutor.getActiveCount()));
            result.add(new Metric<Number>(String.format(pattern, "incrTaskExecutor", "currentPoolSize"), incrTaskExecutor.getPoolSize()));
            result.add(new Metric<Number>(String.format(pattern, "incrTaskExecutor", "maxPoolSize"), incrTaskExecutor.getMaxPoolSize()));
            result.add(new Metric<Number>(String.format(pattern, "incrTaskExecutor", "currentSizeInQueue"), incrTaskExecutor.getThreadPoolExecutor().getQueue().size()));



           /* result.add(new Metric<Number>(String.format(pattern, "incrTaskExecutor", "aciveCount"), incrTaskExecutor.getActiveCount()));
            result.add(new Metric<Number>(String.format(pattern, "incrTaskExecutor", "currentPoolSize"), incrTaskExecutor.getPoolSize()));
            result.add(new Metric<Number>(String.format(pattern, "incrTaskExecutor", "maxPoolSize"), incrTaskExecutor.getMaxPoolSize()));
            result.add(new Metric<Number>(String.format(pattern, "incrTaskExecutor", "currentSizeInQueue"), incrTaskExecutor.getThreadPoolExecutor().getQueue().size()));*/

            /*result.add(new Metric<Number>(String.format(pattern, "dataRateLocalTaskExecutor", "aciveCount"), dataRateLocalTaskExecutor.getActiveCount()));
            result.add(new Metric<Number>(String.format(pattern, "dataRateLocalTaskExecutor", "currentPoolSize"), dataRateLocalTaskExecutor.getPoolSize()));
            result.add(new Metric<Number>(String.format(pattern, "dataRateLocalTaskExecutor", "maxPoolSize"), dataRateLocalTaskExecutor.getMaxPoolSize()));
            result.add(new Metric<Number>(String.format(pattern, "dataRateLocalTaskExecutor", "currentSizeInQueue"), dataRateLocalTaskExecutor.getThreadPoolExecutor().getQueue().size()));

            result.add(new Metric<Number>(String.format(pattern, "dataRateDbTaskExecutor", "aciveCount"), dataRateDbTaskExecutor.getActiveCount()));
            result.add(new Metric<Number>(String.format(pattern, "dataRateDbTaskExecutor", "currentPoolSize"), dataRateDbTaskExecutor.getPoolSize()));
            result.add(new Metric<Number>(String.format(pattern, "dataRateDbTaskExecutor", "maxPoolSize"), dataRateDbTaskExecutor.getMaxPoolSize()));
            result.add(new Metric<Number>(String.format(pattern, "dataRateDbTaskExecutor", "currentSizeInQueue"), dataRateDbTaskExecutor.getThreadPoolExecutor().getQueue().size()));
*/
            return result;
        } catch (Exception e) {
            LOG.error("Async thread pool monitor exception", e);
        }
        return Collections.emptyList();
    }
}
